import struct
import random
import os
import time
from datetime import datetime, timezone, timedelta

class FrameGenerator:
    """帧数据生成器"""
    
    def __init__(self):
        self.FRAME_SIZE = 1092  # 新的帧大小：1092字节
        self.HEADER_VALUE = 1234567890  # 新的帧头固定值
        self.TAIL_VALUE = -1234567890   # 新的帧尾固定值
        self.VCDU_DATA_SIZE = 1024      # VCDU数据区大小
        
    def _get_time_info(self) -> tuple:
        """获取固定的时间信息，确保生成的帧完全相同
        
        Returns:
            tuple: (从2000年1月1日起的积日, 当日积秒(0.1ms), 毫秒数)
        """
        # 使用固定的时间信息
        days = 8000  # 从2000年1月1日起的积日
        deciseconds = 100000  # 当日积秒(0.1ms)
        milliseconds = 500  # 毫秒数
        
        return days, deciseconds, milliseconds
        
    def generate_frame(self, frame_count: int, seed: int = None) -> bytes:
        """生成单个帧数据
        
        Args:
            frame_count: 帧计数值
            seed: 随机数种子，如果指定则使用该种子生成相同的随机数据
            
        Returns:
            bytes: 帧数据字节流
        """
        if seed is not None:
            random.seed(seed)
            
        frame_data = bytearray()
        
        # 帧头(0-3): 固定值1234567890
        frame_data.extend(struct.pack('>i', self.HEADER_VALUE))
        
        # 全帧长度(4-7): 固定值1092
        frame_data.extend(struct.pack('>I', self.FRAME_SIZE))
        
        # 保留字节1(8-11): 值为0
        frame_data.extend(struct.pack('>I', 0))
        
        # 获取时间信息
        days, deciseconds, milliseconds = self._get_time_info()
        
        # 时间标签(12-15): UTC时间信息
        frame_data.extend(struct.pack('>I', days))
        
        # 毫秒计数(16-19)
        frame_data.extend(struct.pack('>I', milliseconds))
        
        # 帧计数(20-23)
        frame_data.extend(struct.pack('>I', frame_count))
        
        # 帧检验结果(24-27): 默认为0表示正确
        frame_data.extend(struct.pack('>I', 0))
        
        # 帧同步状态(28-31): 默认为1表示同步且锁定
        frame_data.extend(struct.pack('>I', 1))
        
        # 位滑状态(32-35): 默认为0表示无位滑
        frame_data.extend(struct.pack('>I', 0))
        
        # 保留字节2(36-39): 值为0
        frame_data.extend(struct.pack('>I', 0))
        
        # VCDU数据区长度(40-43)
        frame_data.extend(struct.pack('>I', self.VCDU_DATA_SIZE))
        
        # 同步字长度(44-47): 默认32bit
        frame_data.extend(struct.pack('>I', 32))
        
        # 帧检验&译码状态(48-51): 默认为0
        frame_data.extend(struct.pack('>I', 0))
        
        # 帧校验及同步字状态(52-55): 默认为0
        frame_data.extend(struct.pack('>I', 0))
        
        # 保留字节3(56-59): 值为0
        frame_data.extend(struct.pack('>I', 0))
        
        # 保留字节4(60-63): 值为0
        frame_data.extend(struct.pack('>I', 0))
        
        # VCDU数据区(64-1087): 1024字节随机数据
        payload = bytes([random.randint(0, 255) for _ in range(self.VCDU_DATA_SIZE)])
        frame_data.extend(payload)
        
        # 帧尾(1088-1091): 固定值-1234567890
        frame_data.extend(struct.pack('>i', self.TAIL_VALUE))
        
        return bytes(frame_data)
    
    def generate_file(self, output_path: str, num_frames: int = 10, start_frame: int = 0, append: bool = False, seed: int = None):
        """生成帧数据文件
        
        Args:
            output_path: 输出文件路径
            num_frames: 帧数量，默认10帧
            start_frame: 起始帧计数，默认0
            append: 是否追加到文件末尾，默认False
            seed: 随机数种子，如果指定则使用该种子生成相同的随机数据
        """
        try:
            # 确保输出目录存在
            os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
            
            # 生成并写入帧数据
            with open(output_path, 'ab' if append else 'wb') as f:
                for i in range(num_frames):
                    # 如果指定了seed，为每一帧生成唯一的种子
                    frame_seed = seed + i if seed is not None else None
                    frame_data = self.generate_frame(start_frame + i, frame_seed)
                    f.write(frame_data)
            
            print(f"成功生成帧数据文件: {output_path}")
            print(f"文件大小: {os.path.getsize(output_path)} 字节")
            print(f"帧数量: {num_frames}")
            
        except Exception as e:
            print(f"生成帧数据文件失败: {str(e)}")
            raise

    def generate_standard_frame(self, fill_byte: int = 0xAA) -> bytes:
        """生成标准帧数据，用于误码率分析
        
        Args:
            fill_byte: 填充字节值，默认为0xAA
            
        Returns:
            bytes: 标准帧数据字节流
        """
        frame_data = bytearray(self.FRAME_SIZE)
        
        # 帧头(0-3): 固定值1234567890
        frame_data[0:4] = struct.pack('>I', self.HEADER_VALUE)
        
        # 全帧长度(4-7): 固定值1092
        frame_data[4:8] = struct.pack('>I', self.FRAME_SIZE)
        
        # 保留字节1(8-11): 值为0
        frame_data[8:12] = struct.pack('>I', 0)
        
        # 获取时间信息
        days, deciseconds, milliseconds = self._get_time_info()
        
        # 时间标签(12-15): UTC时间信息
        frame_data[12:16] = struct.pack('>I', days)
        
        # 毫秒计数(16-19)
        frame_data[16:20] = struct.pack('>I', milliseconds)
        
        # 帧计数(20-23): 设为0
        frame_data[20:24] = struct.pack('>I', 0)
        
        # 帧检验结果(24-27): 默认为0表示正确
        frame_data[24:28] = struct.pack('>I', 0)
        
        # 帧同步状态(28-31): 默认为1表示同步且锁定
        frame_data[28:32] = struct.pack('>I', 1)
        
        # 位滑状态(32-35): 默认为0表示无位滑
        frame_data[32:36] = struct.pack('>I', 0)
        
        # 保留字节2(36-39): 值为0
        frame_data[36:40] = struct.pack('>I', 0)
        
        # VCDU数据区长度(40-43)
        frame_data[40:44] = struct.pack('>I', self.VCDU_DATA_SIZE)
        
        # 同步字长度(44-47): 默认32bit
        frame_data[44:48] = struct.pack('>I', 32)
        
        # 帧检验&译码状态(48-51): 默认为0
        frame_data[48:52] = struct.pack('>I', 0)
        
        # 帧校验及同步字状态(52-55): 默认为0
        frame_data[52:56] = struct.pack('>I', 0)
        
        # 保留字节3(56-59): 值为0
        frame_data[56:60] = struct.pack('>I', 0)
        
        # 保留字节4(60-63): 值为0
        frame_data[60:64] = struct.pack('>I', 0)
        
        # VCDU数据区(64-1087): 1024字节，使用指定的填充数据
        for i in range(64, 1088):
            frame_data[i] = fill_byte
        
        # 帧尾(1088-1091): 固定值-1234567890
        frame_data[1088:1092] = struct.pack('>i', self.TAIL_VALUE)
        
        return bytes(frame_data)

def main():
    """主函数"""
    try:
        generator = FrameGenerator()
        
        # 生成第一个文件的10帧数据
        generator.generate_file(
            output_path="frames1.raw",
            num_frames=10,
            start_frame=0,
            seed=42  # 使用固定的随机种子
        )
        
        # 生成第二个文件
        # 前5帧与第一个文件相同（使用相同的帧计数和随机种子）
        generator.generate_file(
            output_path="frames2.raw",
            num_frames=5,
            start_frame=0,  # 前5帧使用相同的帧计数
            seed=42  # 使用相同的随机种子
        )
        
        # 后5帧使用不同的帧计数和随机数据
        generator.generate_file(
            output_path="frames2.raw",
            num_frames=5,
            start_frame=10,  # 后5帧使用不同的帧计数
            append=True  # 追加到文件末尾
        )
        
        print("\n成功生成两个帧数据文件:")
        print("1. frames1.raw - 10帧数据")
        print("2. frames2.raw - 10帧数据（前5帧与frames1.raw相同，后5帧不同）")
        
        print("\n提示：生成的是二进制raw格式文件，每帧1092字节，帧结构如下：")
        print("- 帧头(0-3): 4字节整型，固定值1234567890")
        print("- 全帧长度(4-7): 4字节整型，固定值1092")
        print("- 保留字节1(8-11): 4字节整型，值为0")
        print("- 时间标签(12-15): 4字节整型，UTC时间信息")
        print("- 毫秒计数(16-19): 4字节整型")
        print("- 帧计数(20-23): 4字节整型")
        print("- VCDU数据区(64-1087): 1024字节")
        print("- 帧尾(1088-1091): 4字节整型，固定值-1234567890")
        
    except Exception as e:
        print(f"执行失败: {str(e)}")

if __name__ == "__main__":
    main() 